#include "data_es.h"

#include "log.h"

namespace chat {
// ESClientFactory

std::shared_ptr<elasticlient::Client> ESClientFactory::create(
    const std::vector<std::string> host_list) {
    return std::make_shared<elasticlient::Client>(host_list);
}

// -------------------------------------------------------------------

// ESUser

bool ESUser::createIndex() {
    ESIndex es_index(client_, "user", "_doc");
    es_index.append("uid", "keyword", "standard", true);
    es_index.append("phone", "keyword", "standard", true);
    es_index.append("nickname", "text", "ik_max_word", true);
    es_index.append("description", "text", "standard", false);
    es_index.append("avatar_id", "keyword", "standard", false);
    if (!es_index.create()) {
        LOG_ERROR("User 索引创建失败");
        return false;
    }

    return true;
}

bool ESUser::appendData(const std::string &uid, const std::string &phone,
                        const std::string &nickname,
                        const std::string &description,
                        const std::string &avatar_id) {
    ESInsert es_insert(client_, "user", "_doc");
    es_insert.append("uid", uid);
    es_insert.append("phone", phone);
    es_insert.append("nickname", nickname);
    es_insert.append("description", description);
    es_insert.append("avatar_id", avatar_id);
    if (!es_insert.insert(uid)) {
        LOG_ERROR("{} User数据新增/修改失败", uid);
        return false;
    }

    return true;
}

std::vector<User> ESUser::search(const std::string &key,
                                 const std::vector<std::string> &ids) {
    std::vector<User> ret;

    ESSearch es_search(client_, "user", "_doc");
    es_search.appendShouldMatch("uid.keyword", key);  // uid 做关键字
    es_search.appendShouldMatch("phone.keyword", key);    // phone 做关键字
    es_search.appendShouldMatch("nickname", key);         // nickname 可被分词
    es_search.appendMustNotTerm("uid.keyword", ids);
    Json::Value root = es_search.search();
    if (root.isArray() == false) {
        LOG_ERROR("User搜索搜索失败");
        return ret;
    }

    for (unsigned int i = 0; i < root.size(); ++i) {
        User user;
        user.user_id(root[i]["_source"]["uid"].asString());
        user.nickname(root[i]["_source"]["nickname"].asString());
        user.phone(root[i]["_source"]["phone"].asString());
        user.description(root[i]["_source"]["description"].asString());
        user.avatar_id(root[i]["_source"]["avatar_id"].asString());

        ret.push_back(user);
    }

    return ret;
}

// -------------------------------------------------------------------

// ESMessage

bool ESMessage::createIndex() {
    ESIndex es_index(client_, "message", "_doc");
    es_index.append("chat_session_id", "keyword", "standard", true);
    es_index.append("message_id", "keyword", "standard", false);
    es_index.append("created_time", "date", "standard", false);
    es_index.append("message_content", "text", "ik_max_word", true);
    es_index.append("user_id", "keyword", "standard", false);
    if (!es_index.create()) {
        LOG_ERROR("Message 索引创建失败");
        return false;
    }

    return true;
}

bool ESMessage::appendData(const std::string &chat_session_id,
                           const std::string &message_id,
                           const boost::posix_time::ptime &create_time,
                           const std::string &message_content,
                           const std::string &user_id) {
    ESInsert es_insert(client_, "message", "_doc");

    es_insert.append("chat_session_id", chat_session_id);
    es_insert.append("message_id", message_id);
    es_insert.append("created_time",
                     boost::posix_time::to_simple_string(create_time));
    es_insert.append("message_content", message_content);
    es_insert.append("user_id", user_id);

    if (!es_insert.insert(message_id)) {
        LOG_ERROR("{} Message数据新增/修改失败", message_id);
        return false;
    }

    return true;
}

std::vector<Message> ESMessage::search(const std::string &key,
                                       const std::string &chat_session_id) {
    std::vector<Message> ret;

    ESSearch es_search(client_, "message", "_doc");
    es_search.appendMustTerm("chat_session_id.keyword", chat_session_id);
    es_search.appendMustMatch("message_content", key);

    Json::Value root = es_search.search();
    if (root.isArray() == false) {
        LOG_ERROR("Message搜索搜索失败");
        return ret;
    }

    LOG_DEBUG("size: {}", root.size());
    for (unsigned int i = 0; i < root.size(); ++i) {
        Message message;
        message.chat_session_id(
            root[i]["_source"]["chat_session_id"].asString());

        message.message_id(root[i]["_source"]["message_id"].asString());

        message.created_time(boost::posix_time::time_from_string(
            root[i]["_source"]["created_time"].asString()));

        message.message_content(
            root[i]["_source"]["message_content"].asString());

        message.user_id(root[i]["_source"]["user_id"].asString());

        ret.push_back(message);
    }

    return ret;
}

bool ESMessage::remove(const std::string &message_id) {
    ESRemove es_remove(client_, "message", "_doc");
    if (!es_remove.remove(message_id)) {
        LOG_ERROR("{} Message数据删除失败", message_id);
        return false;
    }

    return true;
}

}  // namespace chat